package org.hepeng.workx.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.hyperic.sigar.Sigar;
import org.springframework.util.ClassUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @author he peng
 */

@Slf4j
public class SigarUtils {

    private static final String TMPDIR = System.getProperty("java.io.tmpdir");
    private static final String SIGAR_FILE_PREFIX = TMPDIR + File.separatorChar + "sigar" + File.separatorChar;

    private static Sigar SIGAR;

    static {
        ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
        String file = classLoader.getResource("META-INF/sigar/.sigar_shellrc").getFile();
        if (StringUtils.contains(file ,".jar")) {
            copySigarFileFromJarToTmpDir(file);
        } else {
            copySigarFileToTmpDir(file);
        }

        log.info("copy System Information Gatherer And Reporter shell file to system tmp directory ==> {} " , TMPDIR);
        appendJavaLibraryPath();
        SIGAR = new Sigar();
    }

    public static Sigar getSigar() {
        return SIGAR;
    }

    private static void copySigarFileToTmpDir(String file) {
        if (StringUtils.contains(file , "!")) {
            file = StringUtils.remove(file , "!");
            if (StringUtils.startsWith(file , "file:")) {
                file = StringUtils.removeFirst(file , "file:");
                file = new File(file).getAbsolutePath();
            }
        }

        File classPath = new File(file).getParentFile();
        if (StringUtils.contains(classPath.getPath() , "!")) {
            String path = StringUtils.remove(classPath.getPath(), "!");
            classPath = new File(path);
        }

        File sigarFile = new File(SIGAR_FILE_PREFIX);
        try {
            FileUtils.copyDirectory(classPath , sigarFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static void copySigarFileFromJarToTmpDir(String file) {
        int index = StringUtils.indexOf(file, ".jar");
        file = StringUtils.substring(file , 0 , index + 4);
        if (StringUtils.startsWith(file , "file:")) {
            file = StringUtils.removeFirst(file , "file:");
            file = new File(file).getAbsolutePath();
        }
        try {
            JarFile jarFile = new JarFile(file);
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                String entryName = jarEntry.getName();
                if (! StringUtils.equals(entryName , "META-INF/sigar/") &&
                        StringUtils.startsWith(entryName , "META-INF/sigar/")) {

                    String fileName = StringUtils.remove(entryName, "META-INF/sigar/");
                    InputStream inputStream = jarFile.getInputStream(jarEntry);
                    File sigarFile = new File(SIGAR_FILE_PREFIX + fileName);
                    FileUtils.copyInputStreamToFile(inputStream , sigarFile);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void appendJavaLibraryPath() {
        String path = System.getProperty("java.library.path");
        try {
            File sigarFile = new File(SIGAR_FILE_PREFIX);

            if (SystemUtils.IS_OS_WINDOWS) {
                path += ";" + sigarFile.getCanonicalPath();
            } else {
                path += ":" + sigarFile.getCanonicalPath();
            }
            System.setProperty("java.library.path", path);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("append java.library.path ==> {} " , path);
    }
}
